using System.Reflection;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using UniversalAdminSystem.Application.UserManagement.Interface;
using UniversalAdminSystem.Domian.PermissionManagement.IRepository;
using UniversalAdminSystem.Domian.UserManagement.IRepository;
using UniversalAdminSystem.Domian.FileStorage.IRepository;
using UniversalAdminSystem.Domian.LogManagement.IRepository;
using UniversalAdminSystem.Domian.SystemSettings.IRepository;
using UniversalAdminSystem.Domian.Core.Interfaces;
using UniversalAdminSystem.Domian.LogManagement.Aggregates;
using UniversalAdminSystem.Domian.SystemSettings.Aggregates;
using UniversalAdminSystem.Infrastructure.Auth;
using UniversalAdminSystem.Infrastructure.Persistence.DbContexts;
using UniversalAdminSystem.Infrastructure.Persistence.Repositories;
using UniversalAdminSystem.Infrastructure.Services;
using UniversalAdminSystem.Application.PermissionManagement.Interfaces;
using UniversalAdminSystem.Application.PermissionManagement.Services;
using UniversalAdminSystem.Application.Authentication.Interfaces;
using UniversalAdminSystem.Infrastructure.FileStorage;
using FluentValidation;
using UniversalAdminSystem.Domian.UserConversations.IRepository;
using UniversalAdminSystem.Domian.knowledge.IRepository;
using UniversalAdminSystem.Application.FileStorage.Interfaces;
using UniversalAdminSystem.Application.Common.Interfaces;
using UniversalAdminSystem.Infrastructure.RabbitMQ.Queues;
using UniversalAdminSystem.Infrastructure.RabbitMQ;
using UniversalAdminSystem.Infrastructure.RabbitMQ.Publishers;
using UniversalAdminSystem.Infrastructure.RabbitMQ.Consumers;
using RabbitMQ.Client;
using UniversalAdminSystem.Application.AIQuestions.Interfaces;

namespace UniversalAdminSystem.Infrastructure.DependencyInject;

public static class AddInfrastrutureService
{
    /// <summary>
    /// 自动扫描并批量注册仓储接口及其实现（支持接口和实现分布在不同程序集，约定接口名为IXXXRepository，实现名为XXXRepository）
    /// </summary>
    public static IServiceCollection AddRepositoriesByConvention(this IServiceCollection services, Assembly[] interfaceAssemblies, Assembly[] implementationAssemblies)
    {
        var interfaces = interfaceAssemblies
            .SelectMany(a => a.GetTypes())
            .Where(t => t.IsInterface && t.Name.EndsWith("Repository"));
        var implementations = implementationAssemblies
            .SelectMany(a => a.GetTypes())
            .Where(t => t.IsClass && !t.IsAbstract && t.Name.EndsWith("Repository"));

        foreach (var iface in interfaces)
        {
            var impl = implementations.FirstOrDefault(t => iface.IsAssignableFrom(t));
            if (impl != null)
            {
                services.AddScoped(iface, impl);
            }
        }
        return services;
    }

    public static IServiceCollection AddAllConfig(this IServiceCollection services, IConfiguration configuration)
    {
        var asm = Assembly.GetExecutingAssembly();
        var configTypes = asm.GetTypes().Where(t => t.Name.EndsWith("Config")).ToList();

        Console.WriteLine($"找到 {configTypes.Count} 个配置类型:");
        foreach (var type in configTypes)
        {
            Console.WriteLine($"  - {type.Name}");
        }

        foreach (var type in configTypes)
        {
            var sectionName = type.Name.Replace("Config", "");
            Console.WriteLine($"正在注册配置类型: {type.Name} -> 节名: {sectionName}");

            // 检查配置节是否存在
            var section = configuration.GetSection(sectionName);
            Console.WriteLine($"  配置节 {sectionName} 是否存在: {section.Exists()}");

            if (section.Exists())
            {
                // 使用反射调用泛型方法
                var configureMethod = typeof(OptionsConfigurationServiceCollectionExtensions)
                    .GetMethods()
                    .FirstOrDefault(m => m.Name == "Configure" && m.IsGenericMethod && m.GetParameters().Length == 2);

                if (configureMethod != null)
                {
                    try
                    {
                        var genericMethod = configureMethod.MakeGenericMethod(type);
                        genericMethod.Invoke(null, new object[] { services, section });
                        Console.WriteLine($"  成功注册配置类型: {type.Name}");
                    }
                    catch (Exception ex)
                    {
                        Console.WriteLine($"  注册配置类型 {type.Name} 失败: {ex.Message}");
                    }
                }
                else
                {
                    Console.WriteLine($"  未找到 Configure 方法");
                }
            }
            else
            {
                Console.WriteLine($"  配置节 {sectionName} 不存在，跳过注册");
            }
        }
        return services;
    }

    public static IServiceCollection AddInfrastruture(this IServiceCollection services, IConfiguration configuration)
    {
        // 注册数据库上下文
        services.AddDbContext<UniversalAdminSystemDbContext>(x => x.UseNpgsql(configuration.GetConnectionString("pgSql"), x => x.UseVector()));

        // 自动注册所有配置
        services.AddAllConfig(configuration);

        // 自动注册所有仓储
        services.AddRepositoriesByConvention(
            new Assembly[]
            {
                typeof(IUserRepository).Assembly,
                typeof(IUserInfoRepository).Assembly,
                typeof(IPermissionRepository).Assembly,
                typeof(IRoleRepository).Assembly,
                typeof(IFileRepository).Assembly,
                typeof(ILogEntryRepository).Assembly,
                typeof(ISystemSettingRepository).Assembly,
                typeof(IConversationsRepository).Assembly,
                typeof(IDocumentChunkRepository).Assembly,

            },
            new Assembly[]
            {
                typeof(UserRepository).Assembly,
                typeof(UserInfoRepository).Assembly,
                typeof(PermissionRepository).Assembly,
                typeof(RoleRepository).Assembly,
                typeof(FileRepository).Assembly,
                typeof(LogEntryRepository).Assembly,
                typeof(SystemSettingRepository).Assembly,
            }
        );

        // 注册通用IRepository<T>接口到具体实现
        services.AddScoped(typeof(IRepository<LogEntry>), typeof(LogEntryRepository));
        services.AddScoped(typeof(IRepository<SystemSetting>), typeof(SystemSettingRepository));

        // 注册JWT相关服务
        services.AddSingleton<IJwtTokenService, JwtTokenService>();
        services.AddSingleton<JwtTokenBuilder>();
        services.AddScoped<IPasswordHelper, PasswordHelper>();

        // 注册ali的HttpClient服务
        services.AddHttpClient();
        // 注册SpaCy的HttpClient服务
        services.AddHttpClient<SpaCyService>();

        // 注册K2模型相关服务
        services.AddScoped<K2ModelService>();
        services.AddScoped<IFileValidationService, FileValidationService>();

        // 注册SpaCy服务
        services.AddScoped<SpaCyService>();

        // 注册Embedding服务
        services.AddScoped<EmbeddingService>();

        // 注册权限相关服务
        services.AddScoped<IPermissionCheckService, PermissionCheckService>();
        services.AddScoped<IRoleManagementAppService, RoleManagementAppService>();
        services.AddScoped<IPermissionManagementAppService, PermissionManagementAppService>();

        // 注册缓存服务
        services.AddMemoryCache();

        // 注册文件存储服务
        services.AddScoped<IFileStorageService, LocalFileStorageService>();

        // 注册权限规则配置服务
        services.AddHostedService<PermissionInitializationService>();
        services.AddHostedService<SystemInitializationService>();
        services.AddSingleton<SystemPermissionConfigLoader>();

        // // 注册文件处理相关服务
        services.AddScoped<IFileProcessingQueue, EfFileProcessingQueue>();
        services.AddSingleton<IConnection>(sp =>
        {
            var factory = new ConnectionFactory
            {
                Uri = new Uri(sp.GetRequiredService<IConfiguration>().GetConnectionString("RabbitMq")
                              ?? throw new InvalidOperationException("Missing RabbitMq connection string")),
                DispatchConsumersAsync = true
            };
            return factory.CreateConnection();
        });
        services.AddHostedService<RabbitMqTopologyInitializer>();
        services.AddSingleton<IEventBus, RabbitMqEventBus>();
        services.AddHostedService<FileProcessingJobPublisher>();
        services.AddHostedService<FileProcessingJobConsumer>();

        // 注册聊天相关服务
        services.AddScoped<IAnswerService, AnswerService>();
        return services;
    }
}